home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QuickTime - The Beta Release
/
QuickTime - The Beta Release.iso
/
Programming Stuff
/
vdig sample
/
RO364.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-26
|
44KB
|
1,576 lines
/*
File: RO364.c
Contains: xxx put contents here xxx
Written by: xxx put writers here xxx
Copyright: © 1991 by Apple Computer, Inc., all rights reserved.
This file is used in these builds: Warhol
Change History (most recent first):
<33> 8/20/91 PH name changing
<32> 8/20/91 CK Add 3 new calls for async multi buffering support (to possibly
replace the current 2 calls), make the component more PAL
friendly in the rect calls and the input calls
<31> 8/14/91 CK use new rasterops drvr to 1.3d1, change active rect of stv card
to match the current release (might break early stv cards).
<30> 7/23/91 MD fix typo in RegisterComponent
<29> 7/23/91 JB Added register component for linked version
<28> 5/18/91 dvb Thing->Component
<27> 5/9/91 PH only allow 1 thing instance open at a time
<26> 5/7/91 CK fix syntax - barfomatic
<25> 5/7/91 CK nasty 7.0 bug, no card but have thing in open and close.
<24> 5/7/91 CK fix field control flags for 1/2 size requests.
<23> 5/7/91 PH base address slime
<22> 5/6/91 CK auxbuffer slime bug on main screen fixed.
<21> 5/6/91 CK go back to left + 6, last change - ugh!
<20> 5/6/91 CK one last tweak to getactiverect.
<19> 5/6/91 CK no kludge in getmaxsrcrect since seqgrab is now using
getactiverect.
<18> 5/5/91 CK remove SetIdentityMatrix now that we have the register me bit
set (the matrix stuff and toolbox unavailable because open is
called early now)
<17> 5/5/91 CK add set and get pllFilterType (for 24stv)
<16> 5/5/91 CK move to components.h, use newhandle instead of newhandlesys in
open, remove some unused stuff, add bumpOne for auxbuf
<15> 5/2/91 CK Add support for 24STV card, redefine tx, ty calculation with
matrix, fix aux buffer calculation, add 24 STV active rect, init
maxsrc rect global in open
<14> 4/30/91 CK Add 5 new source select routines, update to LSC 4.0.4 headers.
<13> 4/24/91 PH gnarly hack to fix GetMaxSrcRect
<12> 4/18/91 MK fix thing if
<11> 4/18/91 MK add storage to close call
<10> 4/18/91 MK fix thing if
<9> 4/17/91 CK use thing mgr defines for open, close, candoselector, and
getversion; change if to candoselector and getversion due to
thing mgr change
<8> 4/16/91 CK Nuke SetMatrix, Fix Poundoff for mpw, make changes due to matrix
changes, remove outdated & unused i/f, remove save state in
playthru, add pmversion to getauxbuf, fill in color stuff, add
version (#8), add async flag, remove outdated .h files
<7> 3/26/91 CK add playthru calls, change getmaxauxbuffer interface, allocate
pixmap in globals and dispose in exit, add playthru flag in open
<6> 2/24/91 CK Add CanDoSelector and GetVersion calls.
<5> 2/24/91 CK Change to make MPW happy, add 2 new mask calls (v1.0d3), change
errors to VideoDigitizerError, add blendLevels to info, ax the
ReleaseAuxBuffer, ax the exact parameter interface.
<4> 2/23/91 CK Add new calls (v1.0d3), add vdigType in GetDigitizerInfo, add
exact parameter to SetDigitizerRect, change GetMaskgDevice to
GetMaskPixMap.
<3> 2/18/91 CK Add SetIdentity, cleaned up WhackCLUT, removed CheckDestRange,
added AuxBuffer, color control, and GetDigiInfo support, fixed
afew interfaces, added exact parameter, fixed left calculation
in SetDestination, move storage hi before locking
<2> 2/13/91 CK Change I/F matrix stuff, add pound off, add 8 bpp 332 color
support
To Do:
*/
/* RasterOps 364 digitizer wrapper RO364.c */
/*
File name: RO364.c
Function: Code file for the RasterOps 364 digitizer wrapper
History: 1/21/91 New today
To do:
1. SetDigitizerRect - Need to add error checking here
*/
#include "Slots.h"
#include "Files.h"
#include "Memory.h"
#include "Devices.h"
#include "Resources.h"
#include "ToolUtils.h"
#define FALSE 0
#define TRUE 1
#include "Components.h"
#include "Matrix.h"
#include "video digitizer.h"
#include "RO364.h"
#include "Movies.h" /* for kFix1 */
/* private prototypes */
pascal long InitRO364Thing(ComponentInstance self);
pascal long ExitRO364Thing(Handle storage,ComponentInstance self);
pascal long CanDoSelector(short selector);
pascal long GetVersion(void);
Boolean GetRefNum(short order, char *slot, short *refnum, Boolean *haveSTV);
Boolean Get24RefNum( char *slot, short *refnum, short *dRefNum, Boolean *haveSTV );
PixMapHandle GetPMap(short refnum, GDHandle *gd);
long CheckAddressRange(Ptr baddr, Ptr ro364BaseAddr);
long CheckDestRect(short top, short left, short *h, short *v, Boolean *needsClip);
pascal void MatrixCopy( MatrixRecord *mfrom, MatrixRecord *mto);
short Pound364HoldOff( short value, GDHandle gdh );
long PoundSTVHoldOff( short value, short refnum);
pascal void WhackCLUT(short refnum, GDHandle gdh);
pascal void Get332ColorTable(CTabHandle *aCTabHandle);
/*#define realthing*/
#ifdef realthing
pascal ComponentResult main( ComponentParameters *params, Handle storage )
#else
pascal ComponentResult RO364Thing( ComponentParameters *params, Handle storage )
#endif
{
short selector;
/* Debugger();*/
selector = params->what;
if (selector < 0) {
switch (selector) {
case kComponentOpenSelect : {
return CallComponentFunction(params, InitRO364Thing );
}
case kComponentCloseSelect : {
return CallComponentFunctionWithStorage(storage, params, ExitRO364Thing);
}
case kComponentCanDoSelect : {
return CallComponentFunction(params, (ComponentFunction)CanDoSelector);
}
case kComponentVersionSelect : {
return CallComponentFunction(params, (ComponentFunction)GetVersion);
}
default :
return (0);
}
}
else {
switch (selector) {
case kSelectVDGrabOneFrameAsync :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GrabOneFrameAsync);
case kSelectVDGetMaxSrcRect :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetMaxSrcRect);
case kSelectVDGetActiveSrcRect :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetActiveSrcRect);
case kSelectVDSetDigitizerRect :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetDigitizerRect);
case kSelectVDGetDigitizerRect :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetDigitizerRect);
case kSelectVDGetVBlankRect :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetVBlankRect);
case kSelectVDDone :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)Done);
case kSelectVDGetPlayThruDestination :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetPlayThruDestination);
case kSelectVDSetBrightness :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetBrightness);
case kSelectVDGetBrightness :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetBrightness);
case kSelectVDSetContrast :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetContrast);
case kSelectVDSetHue :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetHue);
case kSelectVDSetSaturation :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetSaturation);
case kSelectVDGetContrast :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetContrast);
case kSelectVDGetHue :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetHue);
case kSelectVDGetSaturation :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetSaturation);
case kSelectVDGrabOneFrame :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GrabOneFrame);
case kSelectVDGetMaxAuxBuffer :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetMaxAuxBuffer);
case kSelectVDGetDigitizerInfo :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetDigitizerInfo);
case kSelectVDGetCurrentFlags :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetCurrentFlags);
case kSelectVDSetPLLFilterType :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetPLLFilterType);
case kSelectVDGetPLLFilterType :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetPLLFilterType);
case kSelectVDSetPlayThruDestination :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetPlayThruDestination);
case kSelectVDSetPlayThruOnOff :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetPlayThruOnOff);
case kSelectVDPreflightDestination : return (digiUnimpErr);
case kSelectVDSetBlackLevelValue :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetBlackLevel);
case kSelectVDGetBlackLevelValue :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetBlackLevel);
case kSelectVDSetWhiteLevelValue :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetWhiteLevel);
case kSelectVDGetWhiteLevelValue :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetWhiteLevel);
case kSelectVDGetVideoDefaults :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetVideoDefaults);
case kSelectVDGetNumberOfInputs :
return CallComponentFunction(params, (ComponentFunction)GetNumberOfInputs);
case kSelectVDGetInputFormat :
return CallComponentFunction(params, (ComponentFunction)GetInputFormat);
case kSelectVDSetInput :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetInput);
case kSelectVDGetInput :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetInput);
case kSelectVDSetInputStandard :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetInputStandard);
case kSelectVDSetupBuffers :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetupBuffers);
case kSelectVDGrabOneFrameAsync2 :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GrabOneFrameAsync2);
case kSelectVDDone2 :
return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)Done2);
default : return (digiUnimpErr);
}
};
}
pascal VideoDigitizerError InitRO364Thing(ComponentInstance self) {
Handle h;
Globals *g;
char slot;
short refnum;
short dRefnum;
Rect zeroRect;
GDHandle gd, savegdh;
Boolean have364;
unsigned short tSharpness ;
Boolean haveSTV;
short fref;
long retstat;
if (CountComponentInstances((Component)self) > 1)
return(-1);
/* allocate some private storage in the system heap and lock it down */
h = NewHandle(sizeof(Globals));
MoveHHi(h);
HLock(h);
/* Initialize these fields to somecomponent for now */
g = (Globals *)(*h);
fref = OpenComponentResFile((Component)self);
have364 = Get24RefNum(&slot,&refnum, &dRefnum, &haveSTV);
CloseComponentResFile(fref);
/* have364 = GetRefNum(1,&slot,&refnum); */
if (have364) {
g->haveSTV = haveSTV;
g->pixMapHndl = GetPMap(dRefnum,&gd);
g->destPixMapHndl = NewPixMap();
g->auxBufferPixMapHandle = NewPixMap();
CopyPixMap(g->pixMapHndl, g->auxBufferPixMapHandle);
g->refNum = refnum;
g->gdh = gd;
g->slot = slot;
retstat = GetMaxSrcRect(h,ntscIn,&zeroRect); /* initialize max src rect */
SetRect(&zeroRect,0,0,0,0);
g->digiRect = zeroRect;
g->matrix.matrix[0][0] = kFix1; /* can't call SetIdentityMatrix at register */
g->matrix.matrix[1][1] = kFix1; /* can't call SetIdentityMatrix at register */
g->playThruState = vdPlayThruOff;
g->inputFlags = digiInDoesNTSC |
digiInDoesComposite |
digiInDoesSVideo |
digiInVTR_Broadcast |
digiInDoesColor;
g->outputFlags = digiOutDoes32 |
digiOutDoes8 |
digiOutDoesShrink |
digiOutDoesQuarter |
digiOutDoesSixteenth |
digiOutDoesHorizFlip |
digiOutDoesVertFlip |
digiOutDoesHWPlayThru |
digiOutDoesAsyncGrabs;
if (!g->haveSTV) {
Pound364HoldOff(0,gd);
}
else {
PoundSTVHoldOff(0,g->refNum);
retstat = SetPLLFilterType(h,vdVTRMode); /* Default to VTR mode to avoid sync mess with vcr's */
}
SetComponentInstanceStorage(self,h);
GetVideoDefaults(h, &g->blackLevel, &g->whiteLevel, &g->brightness, &g->hue, &g->saturation, &g->contrast, &tSharpness);
g->inputSource = compositeIn;
g->inputStd = ntscIn;
g->bufferList = 0L;
/* for PAL version only */
/* retstat = SetInputStandard(h,palIn); */
}
else {
DisposHandle(h);
return (-1);
}
return (0);
}
pascal long CanDoSelector(short selector) {
long result = true;
if (selector > kvdigSelectors || selector < kComponentVersionSelect) result = false;
return (result);
}
pascal long GetVersion() {
return ((vdigInterfaceRev<<16) | kCodeRev); /* interface version in hi word, code rev in lo word */
}
pascal VideoDigitizerError ExitRO364Thing(Handle storage,ComponentInstance self ) {
Globals *g;
short error;
#pragma unused(self)
if (storage) {
g = (Globals *)(*storage);
if (g->haveSTV) error = CloseDriver(g->refNum);
if (g->bufferList) DisposHandle ((Handle)g->bufferList);
DisposHandle((Handle)g->destPixMapHndl);
DisposHandle((Handle)g->auxBufferPixMapHandle);
DisposHandle(storage);
}
return (0);
}
pascal VideoDigitizerError GetMaxSrcRect(Handle storage, short inputStd, Rect *maxSrcRect){
CntrlParam pb;
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
if (g->haveSTV) {
switch (g->inputStd) {
case ntscIn : case palIn : case secamIn :
pb.ioCRefNum = g->refNum;
pb.csCode = 9028;
error = PBStatus((ParmBlkPtr)&pb,false);
*maxSrcRect = *((Rect *)pb.csParam);
break;
default :
error = paramErr;
}
}
else if (g->inputStd == ntscIn) {
pb.ioCRefNum = g->refNum;
pb.csCode = 9028;
error = PBStatus((ParmBlkPtr)&pb,false);
*maxSrcRect = *((Rect *)pb.csParam);
}
else error = paramErr;
if (!error)g->maxSrcRect = *maxSrcRect;
return (error);
}
pascal VideoDigitizerError GetActiveSrcRect(Handle storage, short inputStd, Rect *activeSrcRect){
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
if (g->haveSTV) {
switch (g->inputStd) {
case ntscIn :
activeSrcRect->top = g->maxSrcRect.top + 20;
activeSrcRect->left = g->maxSrcRect.left + 54;
activeSrcRect->bottom = g->maxSrcRect.bottom - 8;
activeSrcRect->right = g->maxSrcRect.right - 7;
/* activeSrcRect->top = g->maxSrcRect.top + 20;
activeSrcRect->left = g->maxSrcRect.left;
activeSrcRect->bottom = g->maxSrcRect.bottom - 8;
activeSrcRect->right = g->maxSrcRect.right - 76;
*/
break;
case palIn : case secamIn :
activeSrcRect->top = g->maxSrcRect.top + 20;
activeSrcRect->left = g->maxSrcRect.left + 62;
activeSrcRect->bottom = g->maxSrcRect.bottom - 12;
activeSrcRect->right = g->maxSrcRect.right - 24;
break;
default : error = paramErr;
}
}
else if (g->inputStd == ntscIn) {
activeSrcRect->top = g->maxSrcRect.top + 10;
activeSrcRect->left = g->maxSrcRect.left + 6;
activeSrcRect->bottom = g->maxSrcRect.bottom -10;
activeSrcRect->right = g->maxSrcRect.right - 8;
}
else error = paramErr;
if (!error)g->activeRect = *activeSrcRect;
return (error);
}
pascal VideoDigitizerError GetVBlankRect(Handle storage, short inputStd, Rect *vBlankRect){
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
if (g->inputStd == ntscIn || g->inputStd == palIn || g->inputStd == secamIn) {
g = (Globals *)(*storage);
vBlankRect->top = g->maxSrcRect.top;
vBlankRect->left = g->maxSrcRect.left + 10;
vBlankRect->bottom = g->maxSrcRect.top +10;
vBlankRect->right = g->maxSrcRect.right - 10;
g->vBlankRect = *vBlankRect;
}
else {
error = paramErr;
}
return (error);
}
pascal VideoDigitizerError SetDigitizerRect(Handle storage, Rect *digitizerRect){
Globals *g;
long error = noErr;
/* SetDigitizerRect - Need to add error checking here */
g = (Globals *)(*storage);
g->digiRect = *digitizerRect;
if ((g->digiRect.top % 2) != 0) g->digiRect.top = g->digiRect.top + 1;
if ((g->digiRect.bottom % 2) != 0) g->digiRect.bottom = g->digiRect.bottom + 1;
return (error);
}
pascal VideoDigitizerError GetDigitizerRect(Handle storage, Rect *digitizerRect){
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
*digitizerRect = g->digiRect;
return (error);
}
pascal VideoDigitizerError SetContrast(Handle storage, unsigned short *contrast){
CntrlParam pb;
Globals *g;
long error = noErr;
unsigned short delta;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9009;
pb.csParam[0] = *contrast/1040;
error = PBControl((ParmBlkPtr)&pb,false);
if (!error) {
g->contrast = *contrast;
delta = *contrast%1040;
if (delta != 0)
*contrast = *contrast - delta;
}
return (error);
}
pascal VideoDigitizerError SetHue(Handle storage, unsigned short *hue){
CntrlParam pb;
Globals *g;
long error = noErr;
unsigned short delta;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9006;
pb.csParam[0] = *hue/1040;
error = PBControl((ParmBlkPtr)&pb,false);
if (!error) {
g->hue = *hue;
delta = *hue%1040;
if (delta != 0)
*hue = *hue - delta;
}
return (error);
}
pascal VideoDigitizerError SetBrightness(Handle storage, unsigned short *brightness){
CntrlParam pb;
Globals *g;
long error = noErr;
unsigned short delta;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9008;
pb.csParam[0] = *brightness/1040;
error = PBControl((ParmBlkPtr)&pb,false);
if (!error) {
g->brightness = *brightness;
delta = *brightness%1040;
if (delta != 0)
*brightness = *brightness - delta;
}
return (error);
}
pascal VideoDigitizerError SetSaturation(Handle storage, unsigned short *saturation){
CntrlParam pb;
Globals *g;
long error = noErr;
unsigned short delta;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9007;
pb.csParam[0] = *saturation/1040;
error = PBControl((ParmBlkPtr)&pb,false);
if (!error) {
g->saturation = *saturation;
delta = *saturation%1040;
if (delta != 0)
*saturation = *saturation - delta;
}
return (error);
}
pascal VideoDigitizerError SetBlackLevel(Handle storage, unsigned short *blackLevel){
CntrlParam pb;
Globals *g;
long error = noErr;
unsigned short delta;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9011;
pb.csParam[0] = *blackLevel/1040;
error = PBControl((ParmBlkPtr)&pb,false);
if (!error) {
g->blackLevel = *blackLevel;
delta = *blackLevel%1040;
if (delta != 0)
*blackLevel = *blackLevel - delta;
}
return (error);
}
pascal VideoDigitizerError SetWhiteLevel(Handle storage, unsigned short *whiteLevel){
CntrlParam pb;
Globals *g;
long error = noErr;
unsigned short delta;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9010;
pb.csParam[0] = *whiteLevel/1040;
error = PBControl((ParmBlkPtr)&pb,false);
if (!error) {
g->whiteLevel = *whiteLevel;
delta = *whiteLevel%1040;
if (delta != 0)
*whiteLevel = *whiteLevel - delta;
}
return (error);
}
pascal VideoDigitizerError GetContrast(Handle storage, unsigned short *contrast){
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
*contrast = g->contrast;
return (error);
}
pascal VideoDigitizerError GetHue(Handle storage, unsigned short *hue){
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
*hue = g->hue;
return (error);
}
pascal VideoDigitizerError GetBrightness(Handle storage, unsigned short *brightness){
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
*brightness = g->brightness;
return (error);
}
pascal VideoDigitizerError GetSaturation(Handle storage, unsigned short *saturation){
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
*saturation = g->saturation;
return (error);
}
pascal VideoDigitizerError GetBlackLevel(Handle storage, unsigned short *blackLevel){
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
*blackLevel = g->blackLevel;
return (error);
}
pascal VideoDigitizerError GetWhiteLevel(Handle storage, unsigned short *whiteLevel){
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
*whiteLevel = g->whiteLevel;
return (error);
}
pascal VideoDigitizerError GetVideoDefaults(Handle storage,
unsigned short *blackLevel, unsigned short *whiteLevel,
unsigned short *brightness, unsigned short *hue, unsigned short *saturation,
unsigned short *contrast, unsigned short *sharpness) {
long error = noErr;
/* These values were determined by making status calls to the ro364 driver and recording the defaults */
*blackLevel = 30160;
*whiteLevel = 58240;
*brightness = 33280;
*hue = 33280;
*saturation = 33280;
*contrast = 33280;
*sharpness = 0;
return (error);
}
pascal VideoDigitizerError GrabOneFrame(Handle storage){
CntrlParam pb;
Globals *g;
long error = noErr;
long count;
OSErr ioresult;
g = (Globals *)(*storage);
g->gpb.ioCompletion = 0;
g->gpb.ioCRefNum = g->refNum;
g->gpb.csCode = 9026;
g->gpb.csParam[0] = 1;
error = PBControl((ParmBlkPtr)&g->gpb,false);
return (error);
}
pascal VideoDigitizerError GetMaxAuxBuffer(Handle storage, PixMapHandle *pm, Rect *rect){
Globals *g;
long error = noErr;
short hVisable, vVisable;
g = (Globals *)(*storage);
*pm = g->auxBufferPixMapHandle;
hVisable = (**(*g).pixMapHndl).bounds.right - (**(*g).pixMapHndl).bounds.left;
if ((**(*g).pixMapHndl).pixelSize == 32) {
(***pm).baseAddr = (**(*g).pixMapHndl).baseAddr + ((**(*g).pixMapHndl).pixelSize/8 * hVisable);
(***pm).pmVersion = 4; /* sure it's 32 bit clean */
}
else if ((**(*g).pixMapHndl).pixelSize == 8) {
(***pm).baseAddr = (**(*g).pixMapHndl).baseAddr + (long)hVisable;
(***pm).pmVersion = 4; /* sure it's 32 bit clean */
}
else error = badDepth;
SetRect(&(***pm).bounds,0,0,383,510); /* size of ro364 in 24 bpp */
SetRect(rect,0,0,383,510); /* size of ro364 in 24 bpp */
return (error);
}
pascal VideoDigitizerError GetDigitizerInfo(Handle storage, DigitizerInfo *info){
Globals *g;
long error = noErr;
long in, out;
g = (Globals *)(*storage);
info->vdigType = vdTypeBasic;
info->inputCapabilityFlags = g->inputFlags;
info->outputCapabilityFlags = g->outputFlags;
error = GetCurrentFlags(storage, &in, &out);
info->inputCurrentFlags = in;
info->outputCurrentFlags = out;
info->slot = g->slot;
info->gdh = g->gdh;
info->minDestHeight = 0;
info->minDestWidth = 0;
info->maxDestHeight = g->maxSrcRect.bottom - g->maxSrcRect.top;
info->maxDestWidth = g->maxSrcRect.right - g->maxSrcRect.left;
info->blendLevels = 0;
return (error);
}
pascal VideoDigitizerError GetCurrentFlags(Handle storage, long *inputCurrentFlag, long *outputCurrentFlag) {
CntrlParam pb;
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
/* Get the current input flag information */
pb.ioCRefNum = g->refNum;
pb.csCode = 9005;
error = PBStatus((ParmBlkPtr)&pb,false);
if (pb.csParam[0] == 0) {
*inputCurrentFlag = 0; /* nothing there */
}
else {
*inputCurrentFlag = digiInDoesNTSC | digiInSignalLock;
if (pb.csParam[1] == 0)
*inputCurrentFlag = *inputCurrentFlag | digiInDoesComposite;
else
*inputCurrentFlag = *inputCurrentFlag | digiInDoesSVideo;
}
/* Get the current output flag information */
/* - Currently support pixelSize, shrink, flips only */
*outputCurrentFlag = 0;
if ((**(*g).pixMapHndl).pixelSize == 32) {
*outputCurrentFlag = *outputCurrentFlag | digiOutDoes32;
}
else if ((**(*g).pixMapHndl).pixelSize == 8) {
*outputCurrentFlag = *outputCurrentFlag | digiOutDoes8;
}
else return (error);
if (g->matrix.matrix[1][1] < 0) *outputCurrentFlag = *outputCurrentFlag | digiOutDoesVertFlip;
if (g->matrix.matrix[0][0] < 0) *outputCurrentFlag = *outputCurrentFlag | digiOutDoesHorizFlip;
if ((FixRound(g->matrix.matrix[0][0]) != 1) || (FixRound(g->matrix.matrix[0][0]) != 1))
*outputCurrentFlag = *outputCurrentFlag | digiOutDoesShrink;
return (error);
}
pascal VideoDigitizerError SetPLLFilterType(Handle storage, short pllType) {
CntrlParam pb;
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9034;
pb.csParam[0] = pllType;
error = PBControl((ParmBlkPtr)&pb,false);
return (error);
}
pascal VideoDigitizerError GetPLLFilterType(Handle storage, short *pllType) {
CntrlParam pb;
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9034;
error = PBStatus((ParmBlkPtr)&pb,false);
*pllType = pb.csParam[0];
return (error);
}
pascal VideoDigitizerError SetPlayThruDestination(Handle storage, PixMapHandle dest, Rect *destRect, MatrixRecord *m, RgnHandle mask) {
CntrlParam pb;
Globals *g;
long error = noErr;
Ptr ro364BaseAddr;
short ro364RowBytes;
short top, left;
short hreq, vreq, h1, w1;
short savehreq, savevreq;
short tx, ty;
Boolean hFlip = FALSE;
Boolean vFlip = FALSE;
Boolean needsClip = FALSE;
long lvreq;
Ptr baddr;
short rowBytes;
short pixelSize;
g = (Globals *)(*storage);
ro364BaseAddr = (**(*g).pixMapHndl).baseAddr;
ro364RowBytes = (**(*g).pixMapHndl).rowBytes & 0x7FFF; /* clear high bit set by QD */
baddr = (**dest).baseAddr;
rowBytes = (**dest).rowBytes & 0x7FFF;
pixelSize = (**dest).pixelSize;
/* We have to calculate the following stuff before the test to do scaling in case the dest rect needs clipping
in the translation section.
*/
h1 = g->digiRect.bottom - g->digiRect.top; /* get the current full size height */
w1 = g->digiRect.right - g->digiRect.left; /* get the current full size width */
if (m == 0) {
vreq = destRect->bottom - destRect->top;
hreq = destRect->right - destRect->left;
tx = destRect->left - (*dest)->bounds.left;
ty = destRect->top - (*dest)->bounds.top;
vFlip = FALSE;
hFlip = FALSE;
}
else {
vreq = FixRound(FixMul( (FixRatio(h1,1)),(m->matrix)[1][1])); /* calculate the scaled height */
hreq = FixRound(FixMul( (FixRatio(w1,1)),(m->matrix)[0][0])); /* calculate the scaled width */
tx = FixRound( (m->matrix)[2][0]) - (*dest)->bounds.left;
ty = FixRound( (m->matrix)[2][1]) - (*dest)->bounds.top;
vFlip = ( ((m->matrix)[1][1] < 0) ^ (g->matrix.matrix[1][1] < 0) );
hFlip = ( ((m->matrix)[0][0] < 0) ^ (g->matrix.matrix[0][0] < 0) );
if (vreq < 0) vreq = -vreq;
if (hreq < 0) hreq = -hreq;
}
if ((vreq % 2) != 0) vreq = vreq + 1; /* special adjustment for RO364 */
/* If vreq is adjusted, then a new Sy really needs to be computed (Use CalculateScale),
stored in the matrix and the notExactMatrix warning set.
*/
/* Do the scaling (only if the scale coefficients have changed */
/* This is currently commented out because it won't work right if the digiRect was clipped then unclipped */
/* if (((*matrix)[0][0] != (g->matrix)[0][0]) || ((*matrix)[1][1] != (g->matrix)[1][1])) { */
pb.ioCRefNum = g->refNum;
pb.csCode = 9012;
pb.csParam[0] = g->digiRect.top;
pb.csParam[1] = g->digiRect.left;
pb.csParam[2] = g->digiRect.bottom;
pb.csParam[3] = g->digiRect.right;
pb.csParam[4] = hreq;
pb.csParam[5] = vreq;
if ((hreq <= 640/2) && (vreq <= 480/2)) {
if (g->haveSTV) pb.csParam[6] = 5;
else pb.csParam[6] = 2; /* use even field for 1/2 size or less */
}
else {
pb.csParam[6] = 0; /* use both fields for greater than 1/2 size */
}
error = PBControl((ParmBlkPtr)&pb,false);
/* } */
/* Do the translation */
if (baddr == nil) {
pb.csParam[0] = ty;
pb.csParam[1] = tx;
}
else {
if ((pixelSize != 32) && (pixelSize != 8)) error = badDepth;
/* if ((pixelSize != 32) || ((**(*g).pixMapHndl).pixelSize != 32)) error = badDepth; */
/* if (pixelSize == 8 && pixelSize != g->pixelSize) WhackCLUT(g->refNum,g->gdh); */
if (pixelSize == 8) WhackCLUT(g->refNum,g->gdh);
if (error == 0) error = CheckAddressRange(baddr, ro364BaseAddr); /* make sure it's my screen */
if (error == 0) {
top = (baddr - ro364BaseAddr)/(ro364RowBytes);
if (pixelSize == 32)
left = ((baddr - ro364BaseAddr)/4)%(ro364RowBytes/4);
else
left = (baddr - ro364BaseAddr)%(ro364RowBytes);
top = top + ty;
left = left + tx;
savehreq = hreq;
savevreq = vreq;
error = CheckDestRect(top,left, &hreq, &vreq, &needsClip);
if (needsClip) {
lvreq = (long)vreq * (long)(g->digiRect.bottom - g->digiRect.top);
lvreq = lvreq / (long)savevreq;
savevreq = vreq;
if ((savevreq % 2) != 0) savevreq = savevreq + 1; /* special adjustment for RO364 */
vreq = lvreq;
if ((vreq % 2) != 0) vreq = vreq + 1; /* special adjustment for RO364 */
pb.ioCRefNum = g->refNum;
pb.csCode = 9012;
pb.csParam[0] = g->digiRect.top;
pb.csParam[1] = g->digiRect.left;
pb.csParam[2] = g->digiRect.top + vreq;
pb.csParam[3] = g->digiRect.right;
pb.csParam[4] = savehreq;
pb.csParam[5] = savevreq;
if ((hreq <= 654/2) && (vreq <= 510/2)) {
pb.csParam[6] = 2; /* use even field for 1/2 size or less */
}
else {
pb.csParam[6] = 0; /* use both fields for greater than 1/2 size */
}
error = PBControl((ParmBlkPtr)&pb,false);
}
}
if (error == 0) {
g->bumpOne = false;
if ((top % 2) != 0) {
top = top + 1;
g->bumpOne = true;
}
pb.csParam[0] = top;
pb.csParam[1] = left;
}
}
pb.ioCRefNum = g->refNum;
pb.csCode = 9015;
if (error == 0) error = PBControl((ParmBlkPtr)&pb,false);
/* Do any flipping special effects */
if (hFlip) {
pb.ioCRefNum = g->refNum;
pb.csCode = 9028;
if (error == 0) error = PBControl((ParmBlkPtr)&pb,false);
}
if (vFlip) {
pb.ioCRefNum = g->refNum;
pb.csCode = 9029;
if (error == 0) error = PBControl((ParmBlkPtr)&pb,false);
}
/*** Add other fields to globals here ****/
if (!error) {
CopyPixMap(dest,g->destPixMapHndl);
g->destRect = *destRect;
}
MatrixCopy(m,&(g->matrix));
g->baddr = ro364BaseAddr;
g->rowBytes = rowBytes;
g->pixelSize = pixelSize;
g->top = top;
g->left = left;
/* Save the params for the next time through */
g->nextDest = 0;
return (error);
}
pascal VideoDigitizerError SetPlayThruOnOff(Handle storage, short state)
{
CntrlParam pb;
Globals *g;
long error = noErr;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9024;
pb.csParam[0] = 1; /* Always do full speed */
error = PBControl((ParmBlkPtr)&pb,false);
if (!error) {
pb.csCode = 9025;
switch (state) {
case vdPlayThruOn : {
pb.csParam[0] = 1;
break;
}
case vdPlayThruOff : {
pb.csParam[0] = 0;
break;
}
default : {
return (paramErr);
}
}
pb.csParam[1] = 1; /* Always wait for now */
error = PBControl((ParmBlkPtr)&pb,false);
}
if (!error)g->playThruState = state;
return (error);
}
pascal VideoDigitizerError GetPlayThruDestination(Handle storage, PixMapHandle *dest, Rect *destRect,
MatrixRecord *m, RgnHandle *mask) {
Globals *g;
long error = 0;
g = (Globals *)(*storage);
CopyPixMap(g->destPixMapHndl,*dest);
*destRect = g->destRect;
MatrixCopy(&(g->matrix),m);
*mask = 0L;
return (error);
}
pascal VideoDigitizerError GrabOneFrameAsync(Handle storage, Boolean bufferingOn, PixMapHandle nextDest, Point nextDestPt) {
Globals *g;
long error = 0;
Ptr baddr;
short t, l;
CntrlParam pb;
g = (Globals *)(*storage);
if (bufferingOn) {
if (g->nextDest == 0) {
t = g->top;
l = g->left;
}
else {
baddr = (**g->nextDest).baseAddr;
t = (baddr - g->baddr)/(g->rowBytes) + (g->nextDestPt.v - (*g->nextDest)->bounds.top);
if (g->bumpOne) t += 1; /* slime for ro364 card to stop wiggle ??? */
if ((t % 2) != 0) t = t + 1;
if (g->pixelSize == 32)
l = ((baddr - g->baddr)/4)%(g->rowBytes/4) + (g->nextDestPt.h - (*g->nextDest)->bounds.left);
else
l = (baddr - g->baddr)%(g->rowBytes) + (g->nextDestPt.h - (*g->nextDest)->bounds.left);
}
g->gpb.csParam[0] = t;
g->gpb.csParam[1] = l;
g->gpb.ioCRefNum = g->refNum;
g->gpb.csCode = 9015;
error = PBControl((ParmBlkPtr)&g->gpb,false);
}
/* Do the async frame grab */
g->gpb.ioCompletion = 0;
g->gpb.ioCRefNum = g->refNum;
g->gpb.csCode = 9026;
g->gpb.csParam[0] = 0;
error = PBControl((ParmBlkPtr)&g->gpb,true);
/* Save the params for the next time through */
g->nextDest = nextDest;
g->nextDestPt = nextDestPt;
return (error);
}
pascal long Done(Handle storage) {
long retstat;
long error;
Globals *g;
CntrlParam pb;
retstat = false;
g = (Globals *)(*storage);
pb.ioCompletion = 0;
pb.ioCRefNum = g->refNum;
pb.csCode = 9026;
error = PBStatus((ParmBlkPtr)&pb,false);
if (pb.csParam[0] == 0) retstat = true;
return (retstat);
}
pascal VideoDigitizerError GetNumberOfInputs(short *inputs) {
long error = noErr;
*inputs = 2;
return (error);
}
pascal VideoDigitizerError GetInputFormat(short input, short *format) {
long error = noErr;
switch (input) {
case 0 : {
*format = compositeIn;
break;
}
case 1 : {
*format = sVideoIn;
break;
}
default : {
return (paramErr);
}
}
return (error);
}
pascal VideoDigitizerError SetInput(Handle storage, short input){
long error = noErr;
Globals *g;
CntrlParam pb;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9005;
pb.csParam[0] = input;
error = PBControl((ParmBlkPtr)&pb,false);
if (!error) g->inputSource = input;
return (error);
}
pascal VideoDigitizerError GetInput(Handle storage, short *input){
long error = noErr;
Globals *g;
g = (Globals *)(*storage);
*input = g->inputSource;
return (error);
}
pascal VideoDigitizerError SetInputStandard(Handle storage, short inputStandard){
long error = noErr;
Globals *g;
CntrlParam pb;
g = (Globals *)(*storage);
pb.ioCRefNum = g->refNum;
pb.csCode = 9038;
switch (inputStandard) {
case ntscIn :
pb.csParam[0] = 0;
break;
case palIn :
pb.csParam[0] = 1;
break;
case secamIn :
pb.csParam[0] = 2;
break;
case autoDetectIn :
error = paramErr;
break;
}
if (!error) g->inputStd = inputStandard;
error = PBControl((ParmBlkPtr)&pb,false);
return (error);
}
pascal VideoDigitizerError SetupBuffers(Handle storage, VdigBufferRecListHandle bufferList){
long error = noErr;
Globals *g;
short i;
PixMapHandle theDest;
Point thePoint;
Ptr baddr;
short t, l;
g = (Globals *)(*storage);
if (!g->bufferList) {
g->bufferList = (VdigBufferLocalListHandle)NewHandle( sizeof(VdigBufferLocalList) +
(**bufferList).count * sizeof(VdigBufferLocal));
}
else {
DisposHandle((Handle)g->bufferList);
g->bufferList = (VdigBufferLocalListHandle)NewHandle( sizeof(VdigBufferLocalList) +
(**bufferList).count * sizeof(VdigBufferLocal));
}
(**g->bufferList).count = (**bufferList).count;
for (i=0; i<(**bufferList).count; i++) {
theDest = (**bufferList).list[i].dest;
baddr = (**theDest).baseAddr;
thePoint = (**bufferList).list[i].location;
t = (**g->bufferList).list[i].top = (baddr - g->baddr)/(g->rowBytes) + (thePoint.v - (*theDest)->bounds.top);
if (g->bumpOne) (**g->bufferList).list[i].top += 1;
if (((**g->bufferList).list[i].top % 2) != 0) (**g->bufferList).list[i].top += 1;
if (g->pixelSize == 32)
l = (**g->bufferList).list[i].left = ((baddr - g->baddr)/4)%(g->rowBytes/4) + (thePoint.h - (*theDest)->bounds.left);
else
l = (**g->bufferList).list[i].left = (baddr - g->baddr)%(g->rowBytes/4) + (thePoint.h - (*theDest)->bounds.left);
(**g->bufferList).list[i].pixelSize = g->pixelSize;
(**g->bufferList).list[i].doneState = FALSE;
/* validate the destinations */
}
return (error);
}
pascal VideoDigitizerError GrabOneFrameAsync2(Handle storage, short buffer) {
Globals *g;
long error = 0;
CntrlParam pb;
short prevBuffer;
g = (Globals *)(*storage);
/* Do the move */
g->gpb.csParam[0] = (**g->bufferList).list[buffer].top;
g->gpb.csParam[1] = (**g->bufferList).list[buffer].left;
g->gpb.ioCRefNum = g->refNum;
g->gpb.csCode = 9015;
error = PBControl((ParmBlkPtr)&g->gpb,false);
/* Do the async frame grab */
g->gpb.ioCompletion = 0;
g->gpb.ioCRefNum = g->refNum;
g->gpb.csCode = 9026;
g->gpb.csParam[0] = 0;
if (!error) error = PBControl((ParmBlkPtr)&g->gpb,true);
prevBuffer = buffer - 1;
if (prevBuffer < 0) prevBuffer = (**g->bufferList).count - 1;
/* we assume that the previous buffer is done especially since the move must wait
for frame complete */
(**g->bufferList).list[prevBuffer].doneState = TRUE; /* just a guess */
(**g->bufferList).list[buffer].doneState = FALSE; /* current frame is not done yet */
return(error);
}
pascal long Done2(Handle storage, short buffer) {
Globals *g;
long retstat;
retstat = FALSE;
g = (Globals *)(*storage);
if ((**g->bufferList).list[buffer].doneState) retstat = TRUE;
if (!retstat) retstat = Done(storage); /* just in case it's the last one */
return ( retstat );
}
/* Utilities */
Boolean GetRefNum(short order, char *slot, short *refnum, Boolean *haveSTV)
{
SpBlock mySpBlock;
short count;
Boolean retstat = FALSE;
*refnum = 0;
mySpBlock.spSlot = 0;
mySpBlock.spID = 0;
mySpBlock.spExtDev = 0;
mySpBlock.spHwDev = 0;
mySpBlock.spTBMask = 0x000E; /* only key on spDrvrHW */
mySpBlock.spDrvrHW = 0x2AD; /* assigned driver hw id */
count = 0;
while (!SNextTypeSRsrc(&mySpBlock))
{
count++;
if (order == count)
{
*refnum = mySpBlock.spRefNum;
*slot = mySpBlock.spSlot;
retstat = TRUE;
*haveSTV = TRUE;
break;
}
}
if (!retstat) { /* no ro24stv so look for ro364 */
*refnum = 0;
mySpBlock.spSlot = 0;
mySpBlock.spID = 0;
mySpBlock.spExtDev = 0;
mySpBlock.spHwDev = 0;
mySpBlock.spTBMask = 0x000E; /* only key on spDrvrHW */
mySpBlock.spDrvrHW = 0x26F; /* assigned driver hw id */
count = 0;
while (!SNextTypeSRsrc(&mySpBlock))
{
count++;
if (order == count)
{
*refnum = mySpBlock.spRefNum;
*slot = mySpBlock.spSlot;
retstat = TRUE;
*haveSTV = FALSE;
break;
}
}
}
return (retstat);
}
Boolean Get24RefNum( char *slot, short *refnum, short *dRefNum, Boolean *haveSTV )
{
Boolean valid = false;
OSErr error = noErr;
CntrlParam pb;
short count;
Handle r;
valid = GetRefNum( 1, slot, dRefNum, haveSTV);
if (valid) {
if (*haveSTV) {
error = OpenDriver ( "\p.RasterOps24STVPIP1.3d1", refnum );
r = GetNamedResource('DRVR', "\p.RasterOps24STVPIP1.3d1");
DetachResource(r);
HNoPurge(r);
if (error == noErr)
{
pb.ioCRefNum = *refnum;
pb.csCode = 9027; /* reset */
if ((error = PBControl((ParmBlkPtr)&pb,false))==noErr)
{
pb.ioCRefNum = *refnum;
pb.csCode = 9005;
pb.csParam[0] = 0; /* 0 = composite 1 = s video */
error = PBControl((ParmBlkPtr)&pb,false);
}
}
}
else {
*refnum = *dRefNum; /* only one driver for the ro364 */
}
}
return (valid & !error);
}
PixMapHandle GetPMap(short refnum, GDHandle *gdhdl) {
GDHandle gdh;
gdh = GetDeviceList();
while (((*gdh)->gdRefNum != refnum) & (gdh != nil)) {
gdh = GetNextDevice(gdh);
}
if (gdh != nil) {
*gdhdl = gdh;
return ((*gdh)->gdPMap);
}
else {
return (nil);
}
}
long CheckAddressRange(Ptr baddr, Ptr ro364BaseAddr) {
long error = 0;
/* The ro364 card has a maximum mapping area of x=1024 and y=511 */
if ((baddr < ro364BaseAddr) || (baddr > (ro364BaseAddr+1024L*511L))) {
error = noDMA;
}
return (error);
}
long CheckDestRect(short top, short left, short *h, short *v, Boolean *needsClip)
{
long error = 0;
*needsClip = FALSE;
if ((top > 510) || (left > 1023) ) error = noDMA;
if ((top + (*v)) > 510) {
*v = 510 - top;
if ((*v % 2) != 0) *v = *v + 1; /* special adjustment for RO364 */
*needsClip = TRUE;
}
return (error);
}
/* Hopefully this will be added sometime to Movies Routines */
pascal void MatrixCopy( MatrixRecord *mfrom, MatrixRecord *mto)
{
if (mfrom && mto) {
(mto->matrix)[0][0] = (mfrom->matrix)[0][0];
(mto->matrix)[0][1] = (mfrom->matrix)[0][1];
(mto->matrix)[0][2] = (mfrom->matrix)[0][2];
(mto->matrix)[1][0] = (mfrom->matrix)[1][0];
(mto->matrix)[1][1] = (mfrom->matrix)[1][1];
(mto->matrix)[1][2] = (mfrom->matrix)[1][2];
(mto->matrix)[2][0] = (mfrom->matrix)[2][0];
(mto->matrix)[2][1] = (mfrom->matrix)[2][1];
(mto->matrix)[2][2] = (mfrom->matrix)[2][2];
}
}
pascal void WhackCLUT(short refnum, GDHandle gdh) {
GDHandle savegdh;
CTabHandle aCTabHandle;
CntrlParam pb;
long error = noErr;
Size s;
savegdh = GetGDevice();
SetGDevice(gdh);
aCTabHandle = (CTabHandle) NewHandleClear ( sizeof(ColorSpec)*256 + 8);
(**aCTabHandle).ctSeed = GetCTSeed();
(**aCTabHandle).ctSize = 255;
/* RO364 routine that gets a 332 color table doesn't work */
Get332ColorTable(&(aCTabHandle));
SetEntries(0,255,(**aCTabHandle).ctTable);
DisposHandle((Handle)aCTabHandle);
SetGDevice(savegdh);
}
pascal void Get332ColorTable(CTabHandle *aCTabHandle) {
short r,g,b,i;
i = 0;
for (r=0;r<=247;r+=31) {
for (g=0;g<=247;g+=31) {
for (b=0;b<=251;b+=63) {
(***aCTabHandle).ctTable[i].value = i;
(***aCTabHandle).ctTable[i].rgb.red = ~r << 8;
(***aCTabHandle).ctTable[i].rgb.green = ~g << 8;
(***aCTabHandle).ctTable[i].rgb.blue = ~b << 8;
i++;
}
}
}
}
short Pound364HoldOff( short value, GDHandle c364gdh )
{
long slotstart;
long oldlong;
short oldshort;
long *longaddr;
short *shortaddr;
char saveMode;
slotstart = ((long)(**(**c364gdh).gdPMap).baseAddr) & 0xff000000;
longaddr = (long *)(slotstart+0xfe6018);
shortaddr = (short *)(slotstart+0xfe7004);
#if 1
saveMode = true;
SwapMMUMode(&saveMode);
oldlong = *longaddr;
*longaddr = 3L;
oldshort = *shortaddr;
*shortaddr = value;
*longaddr = oldlong;
SwapMMUMode(&saveMode);
return oldshort;
#else
asm{
moveq #1, d0
_SwapMMUMode
move.b d0, -(sp)
move.l longaddr,a0
move.l shortaddr,a1
move.l (a0), d0 ; get current page select
move.l #3, (a0) ; set to our page
move.w value, (a1) ; set the hold off
move.l d0, (a0) ; restore page select
move.b (sp)+, d0
_SwapMMUMode
}
#endif
}
long PoundSTVHoldOff( short value, short refnum) {
CntrlParam pb;
long error = noErr;
pb.ioCRefNum = refnum;
pb.csCode = 9016;
pb.csParam[0] = value;
error = PBControl((ParmBlkPtr)&pb,false);
return (error);
}
Component RegisterRO364Component(void);
Component RegisterRO364Component(void)
{
ComponentDescription foo;
foo.componentType = 'vdig';
foo.componentSubType = ' ';
foo.componentManufacturer = 'rops';
foo.componentFlags = 0;
foo.componentFlagsMask = 0;
return RegisterComponent(&foo, (void *)RO364Thing, 1, 0, 0, 0);
}